using Cysharp.Threading.Tasks;
using Game.Networking.Utils;
using System.Collections.Generic;
using System.Text;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace Game.UI {
	public class ShipTerminalWindow : UIWindow {
		public TMP_Text       TextField;
		public TMP_InputField InputLine = null;
		public Scrollbar      Scrollbar;

		StringBuilder                  _sb = new StringBuilder(4096);
		IComputingUnitUserDataProvider _dataProvider;

		List<string> _sentMessages       = new List<string>();
		int          _historyOffset      = 0;
		bool         _inputFieldSelected = false;

		protected override void Awake() {
			base.Awake();
			InputLine.onSubmit.AddListener(OnTerminalSubmit);


			InputLine.onSelect.AddListener(OnInputFieldSelected);
			InputLine.onDeselect.AddListener(OnInputFieldDeselected);

			var isServer = NetworkOptions.StartServer;
			if ( isServer ) {
				_dataProvider = new ServerComputingUnitUserDataProvider();
			}	else {
				_dataProvider = new ClientComputingUnitUserDataProvider();
			}
			
		}

		private void Start() {
			_dataProvider?.OnTerminalCommandReceived?.Subscribe(this, UpdateText);
			UpdateText();
		}

		private void Update() {
			if ( !_inputFieldSelected ) {
				return;
			}
			if ( Input.GetKeyDown(KeyCode.UpArrow) ) {
				_historyOffset++;
				if ( _historyOffset > _sentMessages.Count ) {
					_historyOffset = _sentMessages.Count - 1;
					if ( _historyOffset < 0 ) {
						_historyOffset = 0;
					}
				}
				SetLastMessageText();
			}
			if ( Input.GetKeyDown(KeyCode.DownArrow) ) {
				_historyOffset--;
				if ( _historyOffset < 0 ) {
					_historyOffset = 0;
				}
				SetLastMessageText();
			}
		}

		public override void OnWindowShow() {
			base.OnWindowShow();
			InputLine.ActivateInputField();
		}

		void SetLastMessageText() {
			if ( _sentMessages.Count == 0 || _historyOffset == 0 ) {
				return;
			}

			var message = _sentMessages[_sentMessages.Count - _historyOffset ];
			InputLine.text = message;
			InputLine.caretPosition = message.Length;
		}

		void UpdateText() {
			var messages = _dataProvider.GetTerminalMessages();
			if ( messages != null ) {
				foreach ( var item in messages ) {
					_sb.AppendLine(item.ToString());
				}
			}
			TextField.text = _sb.ToString();
			_sb.Clear();
			Scrollbar.value = 0;
			//_ = ScrollToEnd();
		}

		void OnTerminalSubmit(string text) {
			if ( Input.GetKey(KeyCode.Escape) ) {
				return;
			}
			
			if ( !string.IsNullOrEmpty(text) ) {
				var sentText = text.TrimEnd('\r', '\n');
				_dataProvider.SendTerminalMessage(sentText);

				_historyOffset = 0;
				if ( _sentMessages.Count == 0 || _sentMessages[_sentMessages.Count - 1] != sentText ) {
					_sentMessages.Add(sentText);
				}
			}
			InputLine.text = string.Empty;
			InputLine.ActivateInputField();
		}

		void OnInputFieldSelected(string _) {
			_inputFieldSelected = true;
			_owner.HasFocus = true;
			
		}

		void OnInputFieldDeselected(string _) {
			_inputFieldSelected = false;
		}

		async UniTask ScrollToEnd() {
			await UniTask.Yield(PlayerLoopTiming.Update);
			Scrollbar.value = 1;
		}
	}
}
